/**
 * @file thread_safe_queue.hpp
 * @date 2021/10/29 11:10
 * 
 * @author harrybao (harrybao@123u.com)
 * 
 * @brief 线程安全的队列
 * 
 * @version v1.0.0
 * 
 * @copyright Copyright © 2021 harrybao All Rights Reserved
 * 
 * @par history:
 * <table>
 * <tr><th>Date                     <th>Version     <th>Author      <th>Description
 * <tr><td>2021/10/29 11:10         <td>1.0.0       <td>harrybao    <td>创建初始版本
 * </table>
 */

#pragma once

#include <queue>
#include <mutex>

namespace hthread {

template<typename T>
class thread_safe_queue {
public:
  bool empty() const {
    std::unique_lock<std::mutex>(m_mtx);
    return m_queue.empty();
  }

  std::size_t size() const {
    std::unique_lock<std::mutex>(m_mtx);
    return m_queue.size();
  }

  void enqueue(const T &element) {
    std::unique_lock<std::mutex>(m_mtx);
    m_queue.emplace(element);
  }

  void enqueue(T &&element) {
    std::unique_lock<std::mutex>(m_mtx);
    m_queue.emplace(std::forward<T>(element));
  }

  bool dequeue(T &result) {
    std::unique_lock<std::mutex>(m_mtx);

    if (m_queue.empty()) {
      return false;
    }

    result = std::move(m_queue.front());
    m_queue.pop();
    return true;
  }
private:
  std::queue<T> m_queue;
  std::mutex m_mtx;
};

}  // namespace hthread